#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#define ll long long
#define maxn 100+5
#pragma GCC optimize(2)
const double eps=1e-11;

void inputMartix(double a[][maxn],int N);
int jacobi(double a[][maxn],double b[],double x[][2],double acc,int N);
double dis(double x[][2],int N);
void swap(int *x,int *y);

int main(){
    double a[maxn][maxn],b[maxn],x[maxn][2],acc;
    int n;
    printf("输入系数矩阵的阶数n(n<=100):");
    scanf("%d",&n);
    printf("输入%d行%d列的系数矩阵\n",n,n);
    inputMartix(a,n);
    printf("输入%d维右端向量\n",n);
    for(int i=1;i<=n;++i)
        scanf("%lf",&b[i]);
    printf("输入精度要求:");
    scanf("%lf",&acc);
    int now=jacobi(a,b,x,acc,n);
    if(now==0 || now==1){
        for(int i=1;i<=n;++i)
            printf("x%d=%10.6lf\n",i,x[i][now]);
    } else 
        printf("迭代失败，请检查是否收敛。\n");
    return 0;
}



inline void inputMartix(double a[][maxn],int N){
    for(int i=1;i<=N;++i)
        for(int j=1;j<=N;++j)
            scanf("%lf",&a[i][j]);
}

inline int jacobi(double a[][maxn],double b[],double x[][2],double acc,int N){
    //x[][pre]:上一个迭代出的解；x[][now]:目前正在算的解
    int count=0,pre=0,now=1;
    for(int i=1;i<=N;++i)
        x[i][pre]=0.0;
    while(count<=100000000){
        for(int i=1;i<=N;++i){
            double sum=0.0;
            for(int j=1;j<=N;++j){
                if(j!=i)
                    sum+=a[i][j]*x[j][pre];
            }
            x[i][now]=(b[i]-sum)/a[i][i];
        }
        if(dis(x,N)-acc<=eps){
            printf("迭代完成,合计%d次\n",count);
            return now;
        }
        else
            swap(&now,&pre);
        ++count;//迭代了100000000次还没收敛，多半是发散了.
    }
    return 2;
}

inline double dis(double x[][2],int N){
    double ans=0.0;
    for(int i=1;i<=N;++i)
        ans+=(x[i][0]-x[i][1])*(x[i][0]-x[i][1]);
    return sqrt(ans);
}

inline void swap(int *x,int *y){
    int temp=*x;
    *x=*y;
    *y=temp;
}